﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;
using FileMigrationTool.Entity;
using System.Threading;
using System.Net;
using System.Transactions;
using log4net;
using log4net.Config;
using System.Diagnostics;
using log4net.Repository.Hierarchy;
using log4net.Appender;

namespace FileMigration
{
    public partial class FileMigration : Form
    {
        private readonly ILog log = LogManager.GetLogger(typeof(FileMigration));
        private const string Title = "File Migration Tool";

        #region Variables
        readonly BackgroundWorker _backgroundWorker0 = new BackgroundWorker();
        readonly BackgroundWorker _backgroundWorker1 = new BackgroundWorker();

        private static bool _proceed = false;

        public static StringBuilder sb = new StringBuilder();
        public static StringBuilder sb2 = new StringBuilder();
        private Object LockObject = new Object();

        private static int adminUserId = 0;

        private int fileExistinDb = 0;
        private int fileNotExistinSystem = 0;
        private int fileExistinDbA = 0;
        private int fileNotExistinSystemA = 0;
        private int fileExistinDbT = 0;
        private int fileNotExistinSystemT = 0;
        //private int fileExistinDbP = 0;
        private int fileNotExistinSystemP = 0;
        private int fileNotExistinSystemPN = 0;

        private static double progress = 0.0;
        private static int finalProgress = 0;

        private string[] profilePicturesList = null;
        #endregion

        public FileMigration()
        {
            InitializeComponent();
            BasicConfigurator.Configure();

            log.Info(EntryLogToFile("FileMigration initiated"));

            // Create a background worker thread that ReportsProgress &
            // SupportsCancellation
            // Hook up the appropriate events.
            _backgroundWorker0.DoWork += new DoWorkEventHandler(backgroundWorker0_DoWork);
            _backgroundWorker0.RunWorkerCompleted += new RunWorkerCompletedEventHandler
                    (backgroundWorker0_ProgressCompleted);
            _backgroundWorker0.WorkerReportsProgress = true;
            _backgroundWorker0.WorkerSupportsCancellation = true;

            _backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            _backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler
                    (backgroundWorker1_ProgressChanged);
            _backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler
                    (backgroundWorker1_ProgressCompleted);
            _backgroundWorker1.WorkerReportsProgress = true;
            _backgroundWorker1.WorkerSupportsCancellation = true;

            try
            {
                toolStripStatusLabel1.Text = ConfigurationManager.AppSettings["toolStripStatusLabel"];
            }
            catch (Exception ex)
            {
                toolStripStatusLabel1.Text = "© 2014 IronOne Technologies (Pvt) Ltd  |  V.2.3.0  [ConfigError!!!]";
                log.Info(ErrorLogToFile(ex));
            }
        }


        private void MigrateButton_Click(object sender, EventArgs e)
        {
            try
            {
                log.Info(EntryLogToFile("MigrateButton_Click"));

                #region Init valiables
                _proceed = false;
                adminUserId = 0;
                fileExistinDb = 0;
                fileNotExistinSystem = 0;
                fileExistinDbA = 0;
                fileNotExistinSystemA = 0;
                fileExistinDbT = 0;
                fileNotExistinSystemT = 0;
                progress = 0.0;
                finalProgress = 0;
                EventLogTextBox.Text = "";
                //fileExistinDbP = 0;
                fileNotExistinSystemP = 0;
                fileNotExistinSystemPN = 0;
                #endregion

                int val = 0;
                if (string.IsNullOrEmpty(IpPortTextBox.Text.Trim()) ||
                    string.IsNullOrEmpty(DatabaseNameTextBox.Text.Trim()) ||
                    string.IsNullOrEmpty(UsernameTextBox.Text.Trim()) ||
                    string.IsNullOrEmpty(PasswordTextBox.Text.Trim()))
                {
                    MessageBox.Show("Please set database connectivity information to continue.", Title);
                }
                else if (string.IsNullOrEmpty(AdminUserIdTextBox.Text.Trim()) || !int.TryParse(AdminUserIdTextBox.Text.Trim(), out val))
                {
                    MessageBox.Show("Please set a valid admin user id to continue.", Title);
                    AdminUserIdTextBox.Focus();
                }
                else if (PathCheckBox.Checked && (profilePicturesList == null || profilePicturesList.Length <= 0))
                {
                    MessageBox.Show("Please set the path to the profile pictures folder to continue.", Title);
                    PathPictureBoxCross.Visible = true;
                }
                else
                {
                    adminUserId = val;
                    infoLabel.Visible = true;
                    infoLabel.Text = "Connecting to the database...";

                    MigrateButton.Text = "Processing...";
                    MigrateButton.Enabled = false;

                    progressBar1.Style = ProgressBarStyle.Marquee;
                    _backgroundWorker0.RunWorkerAsync();
                }

                log.Info(SuccessLogToFile("MigrateButton_Click"));
            }
            catch (Exception ex)
            {
                MigrateButton.Text = "Migrate";
                MigrateButton.Enabled = true;
                infoLabel.Visible = false;

                ExceptionHandler(ex);
                log.Info(ErrorLogToFile(ex));
            }
        }


        private void backgroundWorker0_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                log.Info(EntryLogToFile("backgroundWorker0_DoWork"));

                SetConnectionString();
                _proceed = ConnectivityTest();

                log.Info(SuccessLogToFile("backgroundWorker0_DoWork"));
            }
            catch (Exception)
            {
                _proceed = false;
            }
        }

        private void backgroundWorker0_ProgressCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                log.Info(EntryLogToFile("backgroundWorker0_ProgressCompleted"));

                if (!_proceed)
                {
                    infoLabel.Visible = false;
                    progressBar1.Style = ProgressBarStyle.Continuous;
                    MigrateButton.Enabled = true;
                    MigrateButton.Text = "Migrate";
                    MessageBox.Show("Database connectivity failed. Please check connectivity information.", Title);
                }
                if (_proceed)
                {
                    if (AdminIdValidation())
                    {
                        infoLabel.Text = "Successfully connected to the database.";
                        MigrateButtonProcess2();
                    }
                    else
                    {
                        infoLabel.Visible = false;
                        progressBar1.Style = ProgressBarStyle.Continuous;
                        MigrateButton.Enabled = true;
                        MigrateButton.Text = "Migrate";
                        MessageBox.Show("BoardPAC database admin's user id is invalid.", Title);
                    }
                }

                log.Info(SuccessLogToFile("backgroundWorker0_ProgressCompleted"));
            }
            catch (Exception ex)
            {
                progressBar1.Style = ProgressBarStyle.Continuous;
                MigrateButton.Enabled = true;

                ExceptionHandler(ex);
                log.Info(ErrorLogToFile(ex));
            }
            infoLabel.Visible = false;
        }

        private void MigrateButtonProcess2()
        {
            log.Info(EntryLogToFile("MigrateButtonProcess2"));

            if (_proceed)
            {
                progressBar1.Style = ProgressBarStyle.Continuous;

                if (MessageBox.Show("Are you sure you want to migrate the files to the database?", "Confirm Migration", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    MigrateButton.Text = "Processing...";
                    MigrateButton.Enabled = false;
                    _backgroundWorker1.RunWorkerAsync();
                }
                else
                {
                    MigrateButton.Text = "Migrate";
                    MigrateButton.Enabled = true;
                    progressBar1.Value = 0;
                }
            }

            log.Info(SuccessLogToFile("MigrateButtonProcess2"));
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            log.Info(EntryLogToFile("backgroundWorker1_DoWork"));

            double i = 0;
            int docCount = 0;

            using (BoardAppProductEntities entities = new BoardAppProductEntities())
            {
                List<DocVersion> docs = null;
                List<AnnotationShare> annoDocs = null;
                List<AgendaTemplate> agendaDocs = null;

                try
                {
                    #region Common

                    docs = (from x in entities.DocVersions
                            where x.FilePath != null && x.FilePath.Length > 0
                            select x).ToList();

                    annoDocs = (from x in entities.AnnotationShares
                                where x.FilePath != null && x.FilePath.Length > 0
                                select x).ToList();

                    agendaDocs = (from x in entities.AgendaTemplates
                                  where x.FilePath != null && x.FilePath.Length > 0 &&
                                  x.Content != null && x.Content.Length <= 0
                                  select x).ToList();

                    if (docs != null && docs.Count > 0)
                        docCount = docCount + docs.Count;
                    if (annoDocs != null && annoDocs.Count > 0)
                        docCount = docCount + annoDocs.Count;
                    if (agendaDocs != null && agendaDocs.Count > 0)
                        docCount = docCount + agendaDocs.Count;
                    if (profilePicturesList != null && profilePicturesList.Length > 0)
                        docCount = docCount + profilePicturesList.Length;

                    if (docCount == 0) docCount = 1;

                    #endregion
                }
                catch (Exception ex)
                {
                    ExceptionHandler(ex);
                    log.Info(ErrorLogToFile(ex));
                }
            }

            #region DocVersion

            DocVersionProcessing(docCount, ref i);

            #endregion

            #region AnnotationShare

            AnnotationShareProcessing(docCount, ref i);

            #endregion

            #region AgendaTemplate

            AgendaTemplateProcessing(docCount, ref i);

            #endregion

            #region ProfilePicture

            if (PathCheckBox.Checked == true)
                ProfilePictureProcessing(profilePicturesList, docCount, ref i);

            #endregion

            log.Info(SuccessLogToFile("backgroundWorker1_DoWork"));
        }


        private void DocVersionProcessing(int docCount, ref double i)
        {
            log.Info(EntryLogToFile("DocVersionProcessing"));

            List<DocVersion> docs = new List<DocVersion>();
            BoardAppProductEntities context = null;
            int PapersBatchSize = 10;

            try
            {
                PapersBatchSize = int.Parse(ConfigurationManager.AppSettings["PapersBatchSize"]);
            }
            catch (Exception ex)
            {
                PapersBatchSize = 10;
                log.Info(ErrorLogToFile(ex));
            }

            using (BoardAppProductEntities entities = new BoardAppProductEntities())
            {
                //http://stackoverflow.com/questions/20495528/ef4-autodetectchangesenabled-not-found?answertab=active#tab-top
                entities.FileStructures.MergeOption = System.Data.Objects.MergeOption.NoTracking;

                docs = (from x in entities.DocVersions
                        where x.FilePath != null && x.FilePath.Length > 0
                        select x).ToList();
            }

            try
            {
                int fileCount = 0;
                if (docs != null && docs.Count >= 1)
                {
                    try
                    {
                        fileCount = Directory.GetFiles(Path.GetDirectoryName(docs[0].FilePath), "*.bpaper").Length;
                    }
                    catch (Exception er)
                    {
                        fileCount = 0;
                        log.Info(ErrorLogToFile(er));
                    }
                }

                int remainFileCount = fileCount % PapersBatchSize;
                int modFinishNum = fileCount - remainFileCount;

                int inc = 0;
                context = new BoardAppProductEntities();
                context.FileStructures.MergeOption = System.Data.Objects.MergeOption.NoTracking;

                foreach (var item in docs)
                {
                    //Thread.Sleep(200);
                    progress = (double)((++i / docCount) * 100);
                    finalProgress = (int)Math.Ceiling(progress);
                    _backgroundWorker1.ReportProgress(finalProgress);

                    bool isFileExist = context.FileStructures.Where(x => x.RefID == item.VersionId).Any();

                    if (isFileExist)
                    {
                        string logEntry = "[Failure][Board Papers] : Doc version id:" + item.VersionId + " : File path:" + item.FilePath + "  [{File exist in the db}]";
                        EventLog(logEntry);
                        log.Info(EventsForLog(logEntry));

                        fileExistinDb = ++fileExistinDb;
                        continue;
                    }
                    if (File.Exists(item.FilePath)) //Check weather file is available
                    {
                        inc++;

                        // Define a transaction scope for the operations.
                        using (TransactionScope transaction = new TransactionScope())
                        {
                            try
                            {
                                FileStructure newFile = new FileStructure();
                                newFile.Content = File.ReadAllBytes(item.FilePath);
                                newFile.CreatedBy = adminUserId;
                                newFile.CreatedDate = DateTime.Now;
                                newFile.RefID = item.VersionId;
                                newFile.RefType = 0;
                                newFile.DocumentID = Guid.NewGuid();
                                context.FileStructures.AddObject(newFile);

                                if (inc % PapersBatchSize == 0)
                                {
                                    context.SaveChanges();
                                    transaction.Complete();

                                    string logEntry = "[Success][Board Papers] : Doc version id:" + item.VersionId + " : File path:" + item.FilePath;
                                    //EventLog(logEntry);
                                    log.Info(EventsForLog(logEntry));

                                    context = new BoardAppProductEntities();
                                    continue;
                                }

                                //Process remaining records
                                if (inc > modFinishNum)
                                {
                                    context.SaveChanges();
                                    context.Detach(newFile);
                                    transaction.Complete();
                                    
                                    string logEntry = "[Success][Board Papers] : Doc version id:" + item.VersionId + " : File path:" + item.FilePath;
                                    //EventLog(logEntry);
                                    log.Info(EventsForLog(logEntry));
                                }
                            }
                            catch (Exception ew)
                            {
                                string logEntry = "[Failure][Board Papers] : Doc version id:" + item.VersionId + " : File path:" + item.FilePath + "  [{Error occured during the process}]";
                                EventLog(logEntry);
                                log.Info(EventsForLog(logEntry));

                                log.Info(ErrorLogToFile(ew));
                                continue;
                            }
                        }
                    }
                    else
                    {
                        string logEntry = "[Failure][Board Papers] : Doc version id:" + item.VersionId + " : File path:" + item.FilePath + "  [{File not available in the given path}]";
                        EventLog(logEntry);
                        log.Info(EventsForLog(logEntry));

                        fileNotExistinSystem = ++fileNotExistinSystem;
                        continue;
                    }
                }
                // }
            }
            catch (Exception ex)
            {
                ExceptionHandler(ex);
                log.Info(ErrorLogToFile(ex));
            }
            finally
            {
                context.Dispose();
            }

            log.Info(SuccessLogToFile("DocVersionProcessing"));
        }

        private void AnnotationShareProcessing(int docCount, ref double i)
        {
            try
            {
                log.Info(EntryLogToFile("AnnotationShareProcessing"));

                using (BoardAppProductEntities entities = new BoardAppProductEntities())
                {
                    List<AnnotationShare> annoDocs = (from x in entities.AnnotationShares
                                                      where x.FilePath != null && x.FilePath.Length > 0
                                                      select x).ToList();

                    foreach (var item in annoDocs)
                    {
                        //Thread.Sleep(200);
                        progress = (double)((++i / docCount) * 100);
                        finalProgress = (int)Math.Ceiling(progress);
                        _backgroundWorker1.ReportProgress(finalProgress);

                        bool isFileExist = entities.FileStructures.Where(x => x.RefID == item.AnnotationShareId && x.RefType == 1).Any();

                        if (isFileExist)
                        {
                            string logEntry = "[Failure][Annotation] : Annotation share id:" + item.AnnotationShareId + " : File path:" + item.FilePath + "  [{File exist in the db}]";
                            EventLog(logEntry);
                            log.Info(EventsForLog(logEntry));
                            
                            fileExistinDbA = ++fileExistinDbA;
                            continue;
                        }
                        if (File.Exists(item.FilePath)) //Check weather file is available
                        {
                            FileStructure newFile = new FileStructure();
                            newFile.Content = newFile.Content = File.ReadAllBytes(item.FilePath); //Utility.ReadFromFile(item.FilePath);
                            newFile.CreatedBy = adminUserId;
                            newFile.CreatedDate = DateTime.Now;
                            newFile.RefID = item.AnnotationShareId;
                            newFile.RefType = 1;
                            newFile.DocumentID = Guid.NewGuid();

                            entities.FileStructures.AddObject(newFile);
                            entities.SaveChanges();

                            string logEntry = "[Success][Annotation] : Annotation share id:" + item.AnnotationShareId + " : File path:" + item.FilePath;
                            EventLog(logEntry);
                            log.Info(EventsForLog(logEntry));
                        }
                        else
                        {
                            string logEntry = "[Failure][Annotation] : Annotation share id:" + item.AnnotationShareId + " : File path:" + item.FilePath + "  [{File not available in the given path}]";
                            EventLog(logEntry);
                            log.Info(EventsForLog(logEntry));

                            fileNotExistinSystemA = ++fileNotExistinSystemA;
                            continue;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionHandler(ex);
                log.Info(ErrorLogToFile(ex));
            }

            log.Info(SuccessLogToFile("AnnotationShareProcessing"));
        }

        private void AgendaTemplateProcessing(int docCount, ref double i)
        {
            try
            {
                log.Info(EntryLogToFile("AgendaTemplateProcessing"));

                using (BoardAppProductEntities entities = new BoardAppProductEntities())
                {
                    List<AgendaTemplate> agendaDocs = (from x in entities.AgendaTemplates
                                                       where x.FilePath != null && x.FilePath.Length > 0 &&
                                                       x.Content != null && x.Content.Length <= 0
                                                       select x).ToList();

                    foreach (AgendaTemplate item in agendaDocs)
                    {
                        //Thread.Sleep(200);
                        progress = (double)((++i / docCount) * 100);
                        finalProgress = (int)Math.Ceiling(progress);
                        _backgroundWorker1.ReportProgress(finalProgress);

                        bool fileExistance = false;
                        string filePath = "";

                        if (File.Exists(item.FilePath))
                        {
                            fileExistance = true;
                            filePath = item.FilePath;
                        }

                        if (!fileExistance) //fileExistance == false
                        {
                            fileExistance = File.Exists(item.FilePath + "\\" + item.AgendaTemplateId + ".xml");
                            filePath = item.FilePath + "\\" + item.AgendaTemplateId + ".xml";
                        }

                        if (fileExistance) //Check weather file is available
                        {
                            string xml = File.ReadAllText(filePath);
                            string encodedXml = WebUtility.HtmlEncode(xml);

                            item.Content = encodedXml;
                            item.ModifiedBy = adminUserId;
                            item.ModifiedDate = DateTime.Now;
                            entities.SaveChanges();

                            string logEntry = "[Success][AgendaTemplate] : Agenda template id:" + item.AgendaTemplateId + " : File path:" + item.FilePath;
                            EventLog(logEntry);
                            log.Info(EventsForLog(logEntry));
                        }
                        else
                        {
                            string logEntry = "[Failure][AgendaTemplate] : Agenda template id:" + item.AgendaTemplateId + " : File path:" + item.FilePath + "  [{File not available in the given path}]";
                            EventLog(logEntry);
                            log.Info(EventsForLog(logEntry));

                            fileNotExistinSystemT = ++fileNotExistinSystemT;
                            continue;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionHandler(ex);
                log.Info(ErrorLogToFile(ex));
            }

            log.Info(SuccessLogToFile("AgendaTemplateProcessing"));
        }

        private void ProfilePictureProcessing(string[] profilePicturesList, int docCount, ref double i)
        {
            try
            {
                log.Info(EntryLogToFile("ProfilePictureProcessing"));

                using (BoardAppProductEntities entities = new BoardAppProductEntities())
                {
                    foreach (string item in profilePicturesList)
                    {
                        //Thread.Sleep(200);
                        progress = (double)((++i / docCount) * 100);
                        finalProgress = (int)Math.Ceiling(progress);
                        _backgroundWorker1.ReportProgress(finalProgress);

                        int filename = 0;
                        if (File.Exists(item)) //Check weather file is available
                        {
                            try
                            {
                                string[] arr = item.Split('\\');
                                filename = int.Parse(arr[arr.Length - 1].Trim().Split('.')[0]);
                            }
                            catch (Exception er)
                            {
                                log.Info(ErrorLogToFile(er));
                                continue;
                            }

                            User user = entities.Users.Where(x => x.CustomUserId == filename).FirstOrDefault();

                            if (user != null && (user.Image == null || user.Image.Length <= 0))
                            {
                                user.Image = File.ReadAllBytes(item);
                                user.ModifiedBy = adminUserId;
                                user.ModifiedDate = DateTime.Now;
                                user.ImageModifiedDate = DateTime.Now;
                                entities.SaveChanges();

                                string logEntry = "[Success][ProfilePicture] : Profile picture id:" + filename + " : File path:" + item;
                                EventLog(logEntry);
                                log.Info(EventsForLog(logEntry));
                            }
                            else
                            {
                                string logEntry = "[Failure][ProfilePicture] : Profile picture id:" + filename + " : File path:" + item + "  [{User not available or image is already exist in the database}]";
                                EventLog(logEntry);
                                log.Info(EventsForLog(logEntry));
                                
                                fileNotExistinSystemPN = ++fileNotExistinSystemPN;
                                continue;
                            }
                        }
                        else
                        {
                            string logEntry = "[Failure][ProfilePicture] : Profile picture id:" + filename + " : File path:" + item + "  [{File not available in the given path}]";
                            EventLog(logEntry);
                            log.Info(EventsForLog(logEntry));

                            fileNotExistinSystemP = ++fileNotExistinSystemP;
                            continue;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionHandler(ex);
                log.Info(ErrorLogToFile(ex));
            }

            log.Info(SuccessLogToFile("ProfilePictureProcessing"));
        }


        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // Change the value of the ProgressBar to the BackgroundWorker progress.
            progressBar1.Value = e.ProgressPercentage;

            lock (this.LockObject)
            {
                // Set the text.
                this.Text = Title + " (" + e.ProgressPercentage.ToString() + "%)";
                EventLogTextBox.Text = sb.ToString();
            }
        }

        private void backgroundWorker1_ProgressCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                log.Info(EntryLogToFile("backgroundWorker1_ProgressCompleted"));

                progressBar1.Value = 0;
                this.Text = Title;
                MigrateButton.Text = "Migrate";
                MigrateButton.Enabled = true;
                infoLabel.Visible = false;

                if (fileExistinDb == 0 && fileNotExistinSystem == 0 && fileExistinDbA == 0 && fileNotExistinSystemA == 0
                    && fileExistinDbT == 0 && fileNotExistinSystemT == 0 && fileNotExistinSystemP == 0 && fileNotExistinSystemPN == 0)
                    MessageBox.Show("Migration completed successfully.", Title);
                else
                {
                    string errMsg = "Migration completed with failures.\n\n";

                    #region DocVersion
                    if (fileExistinDb == 1)
                        errMsg = errMsg + fileExistinDb + " board paper is already in the database.\n";
                    if (fileExistinDb > 1)
                        errMsg = errMsg + fileExistinDb + " board papers are already in the database.\n";

                    if (fileNotExistinSystem == 1)
                        errMsg = errMsg + fileNotExistinSystem + " board paper is not exist in the file system.\n";
                    if (fileNotExistinSystem > 1)
                        errMsg = errMsg + fileNotExistinSystem + " board papers are not exist in the file system.\n";
                    #endregion

                    #region AnnotationShare
                    if (fileExistinDbA == 1)
                        errMsg = errMsg + fileExistinDbA + " annotation file is already in the database.\n";
                    if (fileExistinDbA > 1)
                        errMsg = errMsg + fileExistinDbA + " annotation files are already in the database.\n";

                    if (fileNotExistinSystemA == 1)
                        errMsg = errMsg + fileNotExistinSystemA + " annotation file is not exist in the file system.\n";
                    if (fileNotExistinSystemA > 1)
                        errMsg = errMsg + fileNotExistinSystemA + " annotation files are not exist in the file system.\n";
                    #endregion

                    #region AgendaTemplate
                    if (fileExistinDbT == 1)
                        errMsg = errMsg + fileExistinDbT + " agenda template file is already in the database.\n";
                    if (fileExistinDbT > 1)
                        errMsg = errMsg + fileExistinDbT + " agenda template files are already in the database.\n";

                    if (fileNotExistinSystemT == 1)
                        errMsg = errMsg + fileNotExistinSystemT + " agenda template file is not exist in the file system.\n";
                    if (fileNotExistinSystemT > 1)
                        errMsg = errMsg + fileNotExistinSystemT + " agenda template files are not exist in the file system.\n";
                    #endregion

                    #region ProfilePicture
                    if (fileNotExistinSystemPN == 1)
                        errMsg = errMsg + fileNotExistinSystemPN + " user not exist in the database or " + fileNotExistinSystemPN + " profile picture is already in the database.\n";
                    if (fileNotExistinSystemPN > 1)
                        errMsg = errMsg + fileNotExistinSystemPN + " users are not exist in the database or " + fileNotExistinSystemPN + " profile pictures are already in the database.\n";

                    if (fileNotExistinSystemP == 1)
                        errMsg = errMsg + fileNotExistinSystemP + " profile picture is not exist in the file system.\n";
                    if (fileNotExistinSystemP > 1)
                        errMsg = errMsg + fileNotExistinSystemP + " profile pictures are not exist in the file system.\n";
                    #endregion

                    errMsg = errMsg + "\nPlease check the event log for complete information.";
                    MessageBox.Show(errMsg, Title);

                    profilePicturesList = null;
                    PathPictureBoxTick.Visible = false;
                    PathPictureBoxCross.Visible = false;
                }
            }
            catch (Exception ex)
            {
                ExceptionHandler(ex);
                log.Info(ErrorLogToFile(ex));
            }

            log.Info(SuccessLogToFile("backgroundWorker1_ProgressCompleted"));
        }


        private void EventLogTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (EventLogTextBox != null && EventLogTextBox.Multiline == true && e.Control == true && e.KeyCode == Keys.A)
                EventLogTextBox.SelectAll();
        }

        private void ImagePathBrowseButton_Click(object sender, EventArgs e)
        {
            log.Info(EntryLogToFile("ImagePathBrowseButton_Click"));
            profilePicturesList = GetDirectory();
            log.Info(SuccessLogToFile("ImagePathBrowseButton_Click"));
        }

        private void LogFileOpenButton_Click(object sender, EventArgs e)
        {
            try
            {
                log.Info(EntryLogToFile("LogFileOpenButton_Click"));

                Hierarchy hierarchy = LogManager.GetRepository() as Hierarchy;
                Logger logger = hierarchy.Root;
                FileAppender appender = logger.Appenders[0] as FileAppender;
                string file = appender.File;

                Process.Start("notepad.exe", file);
                log.Info(SuccessLogToFile("LogFileOpenButton_Click"));
            }
            catch (Exception ex)
            {
                log.Info(ErrorLogToFile(ex));
                ExceptionHandler(ex);
            }
        }

        public string[] GetDirectory()
        {
            try
            {
                log.Info(EntryLogToFile("GetDirectory"));

                DialogResult result = folderBrowserDialog1.ShowDialog();
                if (result == DialogResult.OK)
                {
                    //User selected a folder and pressed the OK button.
                    string[] fileList = Directory.GetFiles(folderBrowserDialog1.SelectedPath, "*.*", SearchOption.TopDirectoryOnly).Where
                        (s => s.EndsWith(".jpg")).ToArray();

                    if (fileList != null && fileList.Length > 0)
                    {
                        PathPictureBoxTick.Visible = true;
                        PathPictureBoxCross.Visible = false;
                    }
                    else
                    {
                        PathPictureBoxTick.Visible = false;
                        PathPictureBoxCross.Visible = true;
                    }

                    return fileList;
                }
            }
            catch (Exception ex)
            {
                ExceptionHandler(ex);
                log.Info(ErrorLogToFile(ex));
            }

            log.Info(SuccessLogToFile("GetDirectory"));
            return null;
        }


        private void SetConnectionString()
        {
            try
            {
                log.Info(EntryLogToFile("SetConnectionString"));

                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

                // Because it's an EF connection string it's not a normal connection string
                // so we pull it into the EntityConnectionStringBuilder instead
                EntityConnectionStringBuilder efb = new EntityConnectionStringBuilder(
                        config.ConnectionStrings.ConnectionStrings["BoardAppProductEntities"].ConnectionString);

                // Then we extract the actual underlying provider connection string
                SqlConnectionStringBuilder sqb = new SqlConnectionStringBuilder(efb.ProviderConnectionString);

                // Now we can set the data source
                sqb.DataSource = IpPortTextBox.Text.Trim();
                sqb.InitialCatalog = DatabaseNameTextBox.Text.Trim();
                sqb.UserID = UsernameTextBox.Text.Trim();
                sqb.Password = PasswordTextBox.Text.Trim();

                // Pop it back into the EntityConnectionStringBuilder 
                efb.ProviderConnectionString = sqb.ConnectionString;

                // And update...
                config.ConnectionStrings.ConnectionStrings["BoardAppProductEntities"]
                    .ConnectionString = efb.ConnectionString;

                config.Save(ConfigurationSaveMode.Modified, true);
                ConfigurationManager.RefreshSection("connectionStrings");
            }
            catch (Exception rr)
            {
                MessageBox.Show("Connectivity section encounter an error.", Title);
                log.Info(ErrorLogToFile(rr));
            }

            log.Info(SuccessLogToFile("SetConnectionString"));
        }

        private bool ConnectivityTest()
        {
            try
            {
                log.Info(EntryLogToFile("ConnectivityTest"));

                using (BoardAppProductEntities entities = new BoardAppProductEntities())
                {
                    entities.Connection.Open();

                    log.Info(SuccessLogToFile("ConnectivityTest"));
                    return true;
                }
            }
            catch (Exception ww)
            {
                log.Info(ErrorLogToFile(ww));
                return false;
            }
        }

        private bool AdminIdValidation()
        {
            try
            {
                log.Info(EntryLogToFile("AdminIdValidation"));

                using (BoardAppProductEntities entities = new BoardAppProductEntities())
                {
                    aspnet_UsersInRoles uir = (from x in entities.aspnet_UsersInRoles
                                               join y in entities.Users on x.UserId equals y.UserId
                                               where y.CustomUserId == adminUserId
                                               select x).FirstOrDefault();

                    if (uir != null)
                    {
                        Guid ADMINISTRATOR = Guid.Parse("8529e60e-818b-49a7-b95d-38e90f244912");
                        if (uir.RoleId.Equals(ADMINISTRATOR))
                        {
                            log.Info(SuccessLogToFile("AdminIdValidation"));
                            return true;
                        }
                    }
                }
                return false;
            }
            catch (Exception re)
            {
                log.Info(ErrorLogToFile(re));
                return false;
            }
        }


        private void ExceptionHandler(Exception e)
        {
            MessageBox.Show("e.Message:\n" + e.Message + "\n\ne.StackTrace:\n" + e.StackTrace + "\n\ne.InnerException:\n" + e.InnerException, Title);
        }

        private void EventLog(string log)
        {
            lock (this.LockObject)
            {
                sb.Append(log + "  [" + DateTime.Now + "]" + Environment.NewLine);
            }
        }

        private string EventsForLog(string log)
        {
            return log + Environment.NewLine;
        }

        private string EntryLogToFile(string log)
        {
            return "Entry:\t\t" + log + "\t\t";
        }

        private string SuccessLogToFile(string log)
        {
            return "Success:\t" + log + "\t\t";
        }

        private string ErrorLogToFile(Exception exc)
        {
            return Environment.NewLine + Environment.NewLine +
                ">>> Exception Message:" + Environment.NewLine + exc.Message + Environment.NewLine + Environment.NewLine +
                ">>> Inner Exception:" + Environment.NewLine + exc.InnerException + Environment.NewLine + Environment.NewLine +
                ">>> Stack Trace:" + Environment.NewLine + exc.StackTrace;
        }

    }
}